package tzy.viewpager;

import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;


/**
 * Created by Administrator on 2017/11/28 0028.
 */

public class MyViewPager extends ViewPager {
    private AutoScrollPagerObserver mObserver;
    //    private AutoScrollRunnable mRunnable = new AutoScrollRunnable();
    private final AutoScroller mAutoScroller = new AutoScroller();
    private static final long AUTO_SCROLL_INTERVAL = 2000;

    //    private Drawable mPointDrawable;
    private static final int COLOR_CURR = 0XFFFFFFFF;
    private static final int COLOR_OTHER = 0X80FFFFFF;

    private static final int POINTS_MARGIN = 5;
    private static final int MARGIN_BOTTOM = 15;
    private static final int POINT_HEIGHT = 5;
    private final int mPointHeight;
    private final int mPointMargin;
    private final int mMarginBottom;

    private Drawable mSelectedDrawable;
    private Drawable mUnSelectedDrawable;
    private Rect mSelectedRect;
    private Rect mUnSelectedRect;

    public MyViewPager(Context context) {
        this(context, null);
//        mPointDrawable = getResources().getDrawable(R.mipmap.bar_back);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPointPaint = new Paint();
        mPointPaint.setAntiAlias(true);
        final float density = getResources().getDisplayMetrics().density;
        mPointHeight = (int) (density * POINT_HEIGHT);
        mPointMargin = (int) (density * POINTS_MARGIN);
        mMarginBottom = (int) (density * MARGIN_BOTTOM);


//        mPointDrawable = getResources().getDrawable(R.mipmap.bar_back);
    }


    final Paint mPointPaint;

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
//        invalidate();

    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mAutoScroller.stopAutoScroll();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mAutoScroller.startAutoScrollNextPage(false);
                break;
        }


        return super.onInterceptTouchEvent(ev);
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mAutoScroller.stopAutoScroll();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mAutoScroller.startAutoScrollNextPage(false);
                break;
        }


        return super.onTouchEvent(ev);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
//        addOnPageChangeListener(mOnPageChangeListener);
    }

    @Override
    protected void onDetachedFromWindow() {
//        removeOnPageChangeListener(mOnPageChangeListener);
        super.onDetachedFromWindow();
    }


//    static class PagerAdapterConnector extends PagerAdapter {
//        PagerAdapter mAdapter;
//
//        PagerAdapterConnector(PagerAdapter adapter) {
//            mAdapter = adapter;
//        }
//
//
//        @Override
//        public int getItemPosition(Object object) {
//            return POSITION_NONE;
//        }
//
//        public final int getRealPosition(int position) {
//            final int count = getRealCount();
//
//            return count == 0 ? -1 : position < 0 ? -1 : position % getRealCount();
//        }
//
//
//        public int getRealCount() {
//            return mAdapter.getCount();
//        }
//
//        @Override
//        public void destroyItem(ViewGroup container, int position, Object object) {
//            mAdapter.destroyItem(container, position, object);
//        }
//
//        @Override
//        public boolean isViewFromObject(View view, Object object) {
//            return mAdapter.isViewFromObject(view, object);
//        }
//
//        @Override
//        public final Object instantiateItem(ViewGroup container, int position) {
//            return mAdapter.instantiateItem(container, getRealPosition(position));
//        }
//
//
//
//
//        @Override
//        public final int getCount() {
//            final int count = getRealCount();
//            if (count > 1) {
//                return Integer.MAX_VALUE;
//            }
//            return count;
//        }
//    }


    @Override
    public void setAdapter(PagerAdapter adapter) {
        final PagerAdapter oldAdapter = getAdapter();
        if (oldAdapter instanceof MyPagerAdapter) {
            if (mObserver != null) {
                oldAdapter.unregisterDataSetObserver(mObserver);
            }
            final int oldCount = oldAdapter.getCount();
            if (oldCount > 0) {
                mAutoScroller.stopAutoScroll();
            }
        }
        super.setAdapter(adapter);

        if (adapter instanceof MyPagerAdapter) {
            if (mObserver == null) {
                mObserver = new AutoScrollPagerObserver();
            }
            adapter.registerDataSetObserver(mObserver);
            mSelectedDrawable = getResources().getDrawable(((MyPagerAdapter) adapter).getCurrentPointResource());
            fillRect(mSelectedRect == null ? mSelectedRect = new Rect() : mSelectedRect, mSelectedDrawable);
            mUnSelectedDrawable = getResources().getDrawable(((MyPagerAdapter) adapter).getOtherPointResource());
            fillRect(mUnSelectedRect == null ? mUnSelectedRect = new Rect() : mUnSelectedRect, mUnSelectedDrawable);
            mAutoScroller.startAutoScrollNextPage(false);
        } else {
            mSelectedDrawable = null;
            mSelectedRect = null;
            mUnSelectedDrawable = null;
            mUnSelectedRect = null;
        }


    }

    private void fillRect(Rect rect, Drawable drawable) {
        final float scale = (float) mPointHeight / drawable.getIntrinsicHeight();
        rect.set(0, 0, (int) (scale * drawable.getIntrinsicWidth()), (int) (scale * drawable.getIntrinsicHeight()));
    }


    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        if (mSelectedDrawable == null || mUnSelectedDrawable == null)
            return;
        final int curr;
        final int count;
        final PagerAdapter adapter = getAdapter();
        if (adapter instanceof MyPagerAdapter) {
            count = ((MyPagerAdapter) adapter).getRealCount();
            curr = ((MyPagerAdapter) adapter).getRealPosition(getCurrentItem());
        } else {
            count = adapter.getCount();
            curr = getCurrentItem();
        }
        if (count > 0) {
            int points_width = (count - 1) * mUnSelectedRect.width() + mSelectedRect.width();
            int margin_width = (count - 1) * mPointMargin;
            int curLeftEdge = (getWidth() - points_width - margin_width) / 2;
            int curPosition = 0;
            final int y = getHeight() - mMarginBottom - mPointHeight;
            while (curLeftEdge < getWidth() && curPosition < count) {
//                if (curr == curPosition) {
//                    mPointPaint.setColor(COLOR_CURR);
//                    canvas.drawRoundRect(curLeftEdge + getScrollX(), y, );
//                } else {
//                    mPointPaint.setColor(COLOR_OTHER);
//                    canvas.drawCircle(curLeftEdge + getScrollX(), y, mPointHeight / 2, mPointPaint);
//                }

                final Rect currRect;
                if (curr == curPosition) {
                    currRect = mSelectedRect;
                    currRect.offsetTo(curLeftEdge + getScrollX(), y);

                    mSelectedDrawable.setBounds(currRect);
                    mSelectedDrawable.draw(canvas);

                } else {
                    currRect = mUnSelectedRect;
                    currRect.offsetTo(curLeftEdge + getScrollX(), y);

                    mUnSelectedDrawable.setBounds(currRect);
                    mUnSelectedDrawable.draw(canvas);

                }


                ++curPosition;
                curLeftEdge += (currRect.width() + mPointMargin);
            }

        }
//        invalidate();

    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);


    }

    private class AutoScrollPagerObserver extends DataSetObserver {

        @Override
        public void onChanged() {
            super.onChanged();
            mAutoScroller.startAutoScrollNextPage(false);
//            Log.i("@@", "@@onChanged" + getCurrentItem());
        }

        @Override
        public void onInvalidated() {
            super.onInvalidated();
            mAutoScroller.startAutoScrollNextPage(false);
//            Log.i("@@", "@@onInvalidated");
        }
    }


    final class AutoScroller implements Runnable {
        boolean isStarted;

        @Override
        public void run() {
            final int count = getAdapter() == null ? 0 : getAdapter().getCount();

            if (count > 1) {
                int next = getCurrentItem() + 1;
                if (next >= count) {
                    next = 0;
                }
                setCurrentItem(next);
                postDelayed(this, AUTO_SCROLL_INTERVAL);
            } else {
                stopAutoScroll();
                return;
            }
        }

        void startAutoScrollNextPage(boolean timely) {
            stopAutoScroll();
            final PagerAdapter adapter = getAdapter();

            if (adapter != null && adapter instanceof MyPagerAdapter && adapter.getCount() > 0) {
                if (timely) {
                    post(this);
                } else {
                    postDelayed(this, AUTO_SCROLL_INTERVAL);
                }
                isStarted = true;
            }
        }


        void stopAutoScroll() {
            if (isStarted) {
                removeCallbacks(this);
                isStarted = false;
            }
        }


    }


}
